package com.android.flowoflife.hardware;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.util.Log;

import com.android.flowoflife.IFlowOfLifeConstants;

public class HTTPCameraAccess extends AbstractCameraAccess {
	private static final int CONNECT_TIMEOUT = 1000;
	private static final int SOCKET_TIMEOUT = 1000;

	private String url;
	
	public HTTPCameraAccess(String url, int width, int height) {
		super(width, height);
		this.url = url;
	}
	
	@Override
	public void takePicture(ShutterCallback shutterCallback, PictureCallback rawPictureCallback, PictureCallback jpegPictureCallback) {
		HttpURLConnection httpConn = null;
		InputStream in = null;
		try {
			Bitmap bitmap = null;
			
			int response = -1;
			
			//we use URLConnection because it's anticipated that it is lighter-weight than HttpClient
			//NOTE: At this time, neither properly support connect timeouts
			//as a consequence, this implementation will hang on a failure to connect
			URL url = new URL(this.url);
			URLConnection conn = url.openConnection();
			if (!(conn instanceof HttpURLConnection))
				throw new IOException("Not an HTTP connection.");
			
			httpConn = (HttpURLConnection) conn;
			httpConn.setAllowUserInteraction(false);
			httpConn.setConnectTimeout(CONNECT_TIMEOUT);
			httpConn.setReadTimeout(SOCKET_TIMEOUT);
			httpConn.setInstanceFollowRedirects(true);
			httpConn.setRequestMethod("GET");
			httpConn.connect();
			response = httpConn.getResponseCode();
			if (response == HttpURLConnection.HTTP_OK) {
				in = httpConn.getInputStream();
				bitmap = BitmapFactory.decodeStream(in);
				bitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);
				
				shutterCallback.onShutter();
				rawPictureCallback.onPictureTaken(null, null);
				
				ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
				bitmap.compress(CompressFormat.JPEG, 75, outputStream);;
				jpegPictureCallback.onPictureTaken(outputStream.toByteArray(), null);
			}			
			
			if (bitmap == null)
				throw new IOException("Response Code: " + response);
		} catch (Exception e) {
			Log.i(IFlowOfLifeConstants.LOG_TAG, "Failed to obtain image over network", e);
		} finally {
			if (in != null) try {
				in.close();
			} catch (IOException e) {
				/* ignore */
			}
			if (httpConn != null)
				httpConn.disconnect();
		}
	}
}
